/**
 * WeChatVoiceAnimation - 微信风格语音播放动画组件
 *
 * 展示三个同心圆弧，从内到外依次显示，模拟微信语音播放效果
 *
 * 特性：
 * - 使用原生驱动（opacity 动画）
 * - 基于 useFrameAnimationController 实现
 * - 支持自定义颜色、尺寸
 * - 支持外部控制播放/停止
 * - 循环播放
 *
 * 动画效果：
 * - 帧1: 显示1个圆弧（最内层）
 * - 帧2: 显示2个圆弧（内+中）
 * - 帧3: 显示3个圆弧（内+中+外）
 * - 循环
 *
 * @example
 * ```tsx
 * <WeChatVoiceAnimation
 *   playing={isPlaying}
 *   color="#007AFF"
 *   size="medium"
 * />
 * ```
 */

import React, { useMemo, useEffect } from 'react';
import { View, Animated, Easing, StyleSheet } from 'react-native';
import Svg, { Path } from 'react-native-svg';
import { useFrameAnimationController } from '../../hooks/useFrameAnimationController';

/**
 * 组件属性
 */
export interface WeChatVoiceAnimationProps {
  /** 是否播放，默认 false */
  playing?: boolean;

  /** 颜色，默认 '#07C160' (微信绿) */
  color?: string;

  /** 预设尺寸，默认 'medium' */
  size?: 'small' | 'medium' | 'large';

  /** 自定义尺寸（覆盖 size） */
  customSize?: number;

  /** 每帧持续时间（毫秒），默认 300 */
  frameDuration?: number;

  /** 圆弧线宽，默认根据 size 计算 */
  strokeWidth?: number;
}

/**
 * 预设尺寸配置
 */
const SIZE_PRESETS = {
  small: { size: 20, strokeWidth: 1.5 },
  medium: { size: 30, strokeWidth: 2 },
  large: { size: 40, strokeWidth: 2.5 },
};

/**
 * 创建 90度圆弧的 SVG Path
 * @param radius 圆弧半径
 * @param strokeWidth 描边宽度（用于偏移，避免裁剪）
 * @returns SVG Path 字符串
 */
function createArcPath(radius: number, strokeWidth: number): string {
  // 为了避免描边被裁剪，整体偏移半个描边宽度
  const offset = strokeWidth / 2;

  // 圆心在左侧: (offset, radius + offset)
  // 起点：圆心正上方 (offset, offset)
  // 终点：圆心正右方 (radius + offset, radius + offset)
  // 绘制顺时针 90度圆弧，圆弧在右侧
  return `M ${offset} ${offset} A ${radius} ${radius} 0 0 1 ${
    radius + offset
  } ${radius + offset}`;
}

/**
 * 微信风格语音播放动画组件
 */
export function WeChatVoiceAnimation({
  playing = false,
  color = '#07C160', // 微信绿
  size = 'medium',
  customSize,
  frameDuration = 300,
  strokeWidth: customStrokeWidth = 2,
}: WeChatVoiceAnimationProps) {
  // 1. 计算尺寸
  const preset = SIZE_PRESETS[size];
  const containerSize = customSize ?? preset.size;
  const strokeWidth = customStrokeWidth ?? preset.strokeWidth;

  // 3. 定义帧数据（透明度值）
  // 帧1: 只显示最内层 [1, 0, 0]
  // 帧2: 显示内+中层 [1, 1, 0]
  // 帧3: 显示全部 [1, 1, 1]
  const frameData = useMemo(
    () => ({
      arc1Opacity: [1, 1, 1], // 最内层：始终显示
      arc2Opacity: [0, 1, 1], // 中间层：从帧2开始显示
      arc3Opacity: [0, 0, 1], // 最外层：从帧3开始显示
    }),
    [],
  );

  // 2. 使用 Hook
  const {
    animatedValue,
    registerAnimation,
    interpolations,
    play,
    stop,
    isPlaying,
  } = useFrameAnimationController({
    frameData,
    frameCount: 3,
  });

  // 4. 创建并注册动画对象（只在 frameDuration 变化时重建）
  useEffect(() => {
    // 创建循环动画
    const animation = Animated.loop(
      Animated.timing(animatedValue, {
        toValue: 2, // 3帧：0, 1, 2
        duration: frameDuration * 3,
        easing: Easing.linear,
        useNativeDriver: true, // ✅ opacity 支持原生驱动
      }),
    );

    registerAnimation(animation);
  }, [frameDuration, animatedValue, registerAnimation]);

  // 5. 响应外部 playing prop
  useEffect(() => {
    if (playing && !isPlaying) {
      play();
    } else if (!playing && isPlaying) {
      stop();
    }
  }, [playing, isPlaying, play, stop]);

  // 6. 渲染
  if (!interpolations) {
    return null; // 等待 interpolations 注册
  }

  // 使用精确的圆弧数据（半径）
  const arc1Config = {
    radius: 5.78,
    angle: 45,
  };

  const arc2Config = {
    radius: 9.34,
    angle: 45,
  };

  const arc3Config = {
    radius: 13.6,
    angle: 45,
  };

  // 根据 size 计算缩放比例（如果使用了 customSize 则直接使用）
  const scale = customSize
    ? customSize / SIZE_PRESETS.medium.size
    : containerSize / SIZE_PRESETS.medium.size;
  console.log('scale', scale);

  return (
    <View
      style={[
        styles.container,
        {
          // width: containerSize,
          // height: containerSize,
        },
      ]}
    >
      {/* 最内层圆弧 */}
      <Animated.View
        style={[
          styles.arc,
          {
            opacity: interpolations.arc1Opacity,
            transform: [
              { rotate: `${arc1Config.angle}deg` },
              { translateX: (arc1Config.radius * scale + strokeWidth) / 2 },
              { translateY: -(arc1Config.radius * scale + strokeWidth) / 2 },
            ],
          },
        ]}
      >
        <Svg
          width={arc1Config.radius * scale + strokeWidth}
          height={arc1Config.radius * scale + strokeWidth}
        >
          <Path
            d={createArcPath(arc1Config.radius * scale, strokeWidth)}
            stroke={color}
            strokeWidth={strokeWidth}
            fill="none"
            strokeLinecap="round"
          />
        </Svg>
      </Animated.View>

      {/* 中间层圆弧 */}
      <Animated.View
        style={[
          styles.arc,
          {
            opacity: interpolations.arc2Opacity,
            transform: [
              { rotate: `${arc2Config.angle}deg` },
              { translateX: (arc2Config.radius * scale + strokeWidth) / 2 },
              { translateY: -(arc2Config.radius * scale + strokeWidth) / 2 },
            ],
          },
        ]}
      >
        <Svg
          width={arc2Config.radius * scale + strokeWidth}
          height={arc2Config.radius * scale + strokeWidth}
        >
          <Path
            d={createArcPath(arc2Config.radius * scale, strokeWidth)}
            stroke={color}
            strokeWidth={strokeWidth}
            fill="none"
            strokeLinecap="round"
          />
        </Svg>
      </Animated.View>

      {/* 最外层圆弧 */}
      <Animated.View
        style={[
          styles.arc,
          {
            opacity: interpolations.arc3Opacity,
            transform: [
              { rotate: `${arc3Config.angle}deg` },
              { translateX: (arc3Config.radius * scale + strokeWidth) / 2 },
              { translateY: -(arc3Config.radius * scale + strokeWidth) / 2 },
            ],
          },
        ]}
      >
        <Svg
          width={arc3Config.radius * scale + strokeWidth}
          height={arc3Config.radius * scale + strokeWidth}
        >
          <Path
            d={createArcPath(arc3Config.radius * scale, strokeWidth)}
            stroke={color}
            strokeWidth={strokeWidth}
            fill="none"
            strokeLinecap="round"
          />
        </Svg>
      </Animated.View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  arc: {
    position: 'absolute',
    // backgroundColor: 'red',
    opacity: 0.8,
  },
});
